<?php
// +----------------------------------------------------------------------
// | INPHP
// | Copyright (c) 2023 https://inphp.cc All rights reserved.
// | Licensed ( https://opensource.org/licenses/MIT )
// | Author: 幺月儿(https://gitee.com/lulanyin) Email: inphp@qq.com
// +----------------------------------------------------------------------
// | 临时上下文管理
// +----------------------------------------------------------------------
namespace Inphp\Core;

use Inphp\Core\Object\Client;
use Inphp\Core\Services\Http\Response;
use Swoole\Coroutine;

class Context
{
    /**
     * 临时上下文数据
     * 这个对象，仅为了兼容PHP-FPM运行时使用
     * @var array
     */
    public static array $contexts = [];

    /**
     * 获取临时上下文对象
     * @param string $name
     * @param mixed|null $default
     * @return mixed
     */
    public static function get(string $name, mixed $default = null): mixed
    {
        //使用进程ID或协程ID隔离
        $id = Service::isCLI() ? Coroutine::getuid() : getmypid();
        if ($id < 0) {
            return $default;
        }
        return isset(self::$contexts[$id]) && isset(self::$contexts[$id][$name]) ? self::$contexts[$id][$name] : $default;
    }

    /**
     * 保存临时上下文对象
     * @param string $name
     * @param mixed $value
     */
    public static function set(string $name, mixed $value): void
    {
        //使用进程ID或协程ID隔离
        $id = Service::isCLI() ? Coroutine::getuid() : getmypid();
        if ($id < 0) {
            return;
        }
        self::$contexts[$id] = self::$contexts[$id] ?? [];
        self::$contexts[$id][$name] = $value;
    }

    /**
     * 移除临时上下文
     * @param string|null $name
     */
    public static function delete(?string $name = null): void
    {
        //使用进程ID或协程ID隔离
        $id = Service::isCLI() ? Coroutine::getuid() : getmypid();
        if ($id > 0) {
            if (!is_null($name)) {
                unset(self::$contexts[$id][$name]);
            } else {
                unset(self::$contexts[$id]);
            }
        }
    }

    /**
     * 保存客户端对象
     * @param Client $client
     */
    public static function setClient(Client $client): void
    {
        self::set("client", $client);
    }

    /**
     * 获取客户端对象
     * @return Client|null
     */
    public static function getClient(): ?Client
    {
        return self::get("client");
    }

    /**
     * 保存响应对象
     * @param Response $response
     */
    public static function setResponse(Response $response): void
    {
        self::set("response", $response);
    }

    /**
     * 获取响应对象
     * @return Response
     */
    public static function getResponse(): Response
    {
        return self::get("response");
    }

    /**
     * 保存临时的server对象
     * @param \Swoole\Http\Server|\Swoole\WebSocket\Server $server
     */
    public static function setServer(\Swoole\Http\Server|\Swoole\WebSocket\Server $server): void
    {
        self::set("server", $server);
    }

    /**
     * 获取临时保存的server对象
     * @return \Swoole\Http\Server|\Swoole\WebSocket\Server
     */
    public static function getServer(): \Swoole\Http\Server|\Swoole\WebSocket\Server
    {
        return self::get("server");
    }
}